package org.dallasrowing.logbook.ui.view;

import java.util.Date;
import java.util.List;

import org.dallasrowing.logbook.ui.util.MyContentProposalProvider;
import org.dallasrowing.logbook.ui.util.MyContentProposalProvider.ComboProposal;
import org.dallasrowing.logbook.util.FormatUtil;
import org.dallasrowing.model.Boat;
import org.dallasrowing.model.DamageEntry;
import org.eclipse.jface.fieldassist.ComboContentAdapter;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.fieldassist.IContentProposal;
import org.eclipse.jface.fieldassist.IContentProposalListener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class SWTReportNewDamageWindow implements ReportNewDamageWindow {

	private Shell newDamageDialog;
	private Text newDamageCreateDate;
	private Combo boatCombo;
	private ComboModel<Boat> boatComboModel;
	private Text part;
	private Text description;
	private ContentProposalAdapter boatProposalAdapter;
	private Button repairCompleteCheck;
	private Button saveButton;
	private Button cancelButton;
	private Combo currentDamagesCombo;
	private Button newDamageButton;

	public void openReportNewDamageWindow(Shell parent)
	{
		newDamageDialog = new Shell (parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
		newDamageDialog.setText ("Report Damages...");
		newDamageDialog.setLayout(new GridLayout(2, false));
		
		createDamageElements( newDamageDialog );
		
		validateEnableSubmit();
		
		newDamageDialog.setMinimumSize(400, 100 );
		newDamageDialog.pack();
		newDamageDialog.open(); 
	}

	private void createDamageElements(final Shell parent) {
		GridData gridData = new GridData( GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING  );
		Label l = new Label(parent, SWT.NONE);
		l.setText("Current Damages:");
		l.setLayoutData( gridData );
		
		gridData = new GridData( GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING  );
		currentDamagesCombo = new Combo( parent, SWT.DROP_DOWN);
		currentDamagesCombo.setLayoutData(gridData);
		
		gridData = new GridData( GridData.HORIZONTAL_ALIGN_BEGINNING );
		gridData.horizontalSpan = 2;
		newDamageButton = new Button(parent, SWT.NONE);
		newDamageButton.setText("Report new damage...");
		newDamageButton.setLayoutData(gridData);

		createGroupWithDamageDetails(parent);
		
		gridData = new GridData( GridData.HORIZONTAL_ALIGN_CENTER  );
		cancelButton = new Button(parent, SWT.NONE);
		cancelButton.setText("Cancel");
		cancelButton.setLayoutData(gridData);
		cancelButton.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event arg0) {
				closeWindow();
			}
		});
		
		gridData = new GridData( GridData.HORIZONTAL_ALIGN_CENTER  );
		saveButton = new Button(parent, SWT.NONE);
		saveButton.setText("Save");
		saveButton.setLayoutData(gridData);
		saveButton.setEnabled(false);
	}

	private void createGroupWithDamageDetails(final Shell parent) {
		Listener validateListener = new Listener(){
		
			public void handleEvent(Event arg0) {
				validateEnableSubmit();	
			}
		};
		
		GridData gridData = new GridData( GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING  );
		gridData.horizontalSpan = 2;
		Group group = new Group(parent, SWT.BORDER);
		group.setText("Report Details");
		group.setLayout(new GridLayout(2, true));
		group.setLayoutData(gridData);
		
		gridData = new GridData( GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING  );
		Label l = new Label(group, SWT.NONE);
		l.setText("Start Date:");
		l.setLayoutData( gridData );
		
		gridData = new GridData( GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING );
		newDamageCreateDate = new Text(group, SWT.BORDER);
		newDamageCreateDate.setEnabled(false);
		newDamageCreateDate.setLayoutData(gridData);
		
		gridData = new GridData( GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING  );
		l = new Label(group, SWT.NONE);
		l.setText("Boat used:");
		l.setLayoutData( gridData );
		
		gridData = new GridData( GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING );
		boatCombo = new Combo(group, SWT.DROP_DOWN );
		boatCombo.setEnabled(false);
		boatCombo.setLayoutData(gridData);
		boatComboModel = new ComboModel<Boat>();
		boatCombo.addListener(SWT.Modify, validateListener);
		
		gridData = new GridData( GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING  );
		l = new Label(group, SWT.NONE);
		l.setText("Damaged part:");
		l.setLayoutData( gridData );
		
		gridData = new GridData( GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING );
		part = new Text(group, SWT.BORDER);
		part.setTextLimit(500);
		part.setEnabled(false);
		part.setLayoutData(gridData);
		part.addListener(SWT.Modify, validateListener);
		
		gridData = new GridData( GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING  );
		l = new Label(group, SWT.NONE);
		l.setText("Description:");
		l.setLayoutData( gridData );
		
		gridData = new GridData( GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING );
		description = new Text(group, SWT.BORDER);
		description.setTextLimit(500);
		description.setEnabled(false);
		description.setLayoutData(gridData);
		description.addListener(SWT.Modify, validateListener);
		
		gridData = new GridData( GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING  );
		gridData.horizontalSpan = 2;
		repairCompleteCheck = new Button(group, SWT.CHECK);
		repairCompleteCheck.setText("Repair completed");
		repairCompleteCheck.setEnabled(false);
		repairCompleteCheck.setLayoutData( gridData );
		
	}

	private void validateEnableSubmit() {
		boolean enabled = true;

		if (boatCombo.getSelectionIndex() < 0)
		{
			enabled = false;
		}
		
		if (isEmpty(part.getText()))
		{
			enabled = false;
		}
		
		if (isEmpty(description.getText()))
		{
			enabled = false;
		}
		saveButton.setEnabled(enabled);
	}

	private boolean isEmpty(String text) {
		return text == null || text.matches(" *");
	}

	public void populateBoats(List<Boat> boats) {
		boatComboModel.load(boats);

		boatCombo.removeAll();
		for (Boat boat : boats)
		{
			boatCombo.add(boat.getName());
		}

		boatProposalAdapter = new ContentProposalAdapter( boatCombo, 
														  new ComboContentAdapter(),  
														  new MyContentProposalProvider(boatCombo.getItems()), 
														  null, 
														  MyContentProposalProvider.getAlphaNumericChars());
		boatProposalAdapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
		
		boatProposalAdapter.addContentProposalListener(new IContentProposalListener() {
			public void proposalAccepted(IContentProposal proposal) {
				boatCombo.select( ((ComboProposal)proposal).getIndex());
			}
		});
	}

	public void setCreateEntryDate(Date createDate) {
		newDamageCreateDate.setText(FormatUtil.formatDate(createDate));
	}

	public String getCreateEntryDate() {
		return this.newDamageCreateDate.getText();
	}

	public Boat getSelectedBoat() {
		return boatComboModel.getEntryFromIndex( boatCombo.getSelectionIndex());
	}

	public String getDamagedPart() {
		return part.getText();
	}

	public String getDescription() {
		return description.getText();
	}

	public void closeWindow() {
		newDamageDialog.dispose();
	}

	public void setDamagesList(List<DamageEntry> createSimpleDamagesList) {
		for (DamageEntry entry : createSimpleDamagesList)
		{
			currentDamagesCombo.add(entry.getBoat().getName() + ": " + entry.getPart());
		}
	}

	public void setCreateNewEntryListener(final Runnable with) {
		this.newDamageButton.addListener( SWT.Selection, new Listener() {
		
			public void handleEvent(Event arg0) {
				with.run();
			}
		});
		
	}

	public void enableAndWipeAllTextFields() {
		boatCombo.setEnabled(true);
		boatCombo.select(-1);
		part.setEnabled(true);
		part.setText("");
		description.setEnabled(true);
		description.setText("");
		
		currentDamagesCombo.setEnabled(false);
		currentDamagesCombo.select(-1);
		repairCompleteCheck.setEnabled(false);
	}

	public void setSelectDamageListener(final Runnable with) {
		this.currentDamagesCombo.addListener(SWT.Selection, new Listener() {
		
			public void handleEvent(Event arg0) {
				with.run();
			}
		});
	}

	public int getSelectedExistingDamage() {
		return currentDamagesCombo.getSelectionIndex();
	}

	public void populateCurrentDamage(DamageEntry currentDamage, int boatIndex) {
		newDamageCreateDate.setText(FormatUtil.formatDate(currentDamage.getCreateDate()));
		description.setText(currentDamage.getDescription());
		part.setText(currentDamage.getPart());
		boatCombo.select(boatIndex);
		repairCompleteCheck.setEnabled(true);
		//TODO: set boat
	}

	public void setSaveButtonListener(final Runnable runnable) {
		saveButton.addListener(SWT.Selection, new Listener() {
		
			public void handleEvent(Event arg0) {
				runnable.run();
			}
		});
	}

	public DamageEntry getDamageData() {
		DamageEntry damageEntry = new DamageEntry(0, getSelectedBoat(), part.getText(), description.getText(), new Date());
		return damageEntry;
	}

	public boolean getDamageRepairedFlag() {
		return repairCompleteCheck.getSelection();
	}


//	description.addListener(SWT.Modify, validateListener);
//	boatCombo.addListener(SWT.Selection, validateListener);
//	part.addListener(SWT.Modify, validateListener);

}
